/**
 * Project  : Looker
 * Package  : net.freestu.looker.monitor
 * File     : NewsArchiver.java
 * Author   : solosky < solosky772@qq.com >
 * Date     : Aug 23, 2009
 * Modified : Aug 23, 2009
 * License  : Apache License 2.0 
 */
package net.freestu.looker.monitor;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.Callable;

import net.freestu.looker.common.Looker;
import net.freestu.looker.common.Media;
import net.freestu.looker.common.NewsEntity;
import net.freestu.looker.common.NewsMeta;

/**
 *  新闻获取
 *  获取新闻的正文，并提取图片和链接，然后交给下载器下载
 */
public class NewsArchiver implements Callable<NewsEntity>
{
	/**
	 * 新闻对象
	 */
	private NewsEntity newsEntity;
	
	/**
	 * 附件下载器列表
	 */
	private ArrayList<AbstractFetcher> fetcherList;
	
	/**
	 * 构造函数
	 */
	public NewsArchiver(NewsMeta newsMeta)
	{
		newsEntity = newsMeta.toNewsEntity();
		fetcherList = new ArrayList<AbstractFetcher>();
	}
	
	/**
	 * 获取新闻
	 * @throws FetcherException 
	 * @throws InterruptedException 
	 */
	public void archive() throws FetcherException, InterruptedException
	{
		fetchContent();
		parseContent();
		extractMedia();
		fetchMedia();
		filterSuccess();
	}
	
	 /**
	  * 返回提取的新闻
	  */
	public NewsEntity getArchived()
	{
		return this.newsEntity;
	}
	
	/**
	 * 获取新闻正文
	 * @throws FetcherException 
	 */
	private void fetchContent() throws FetcherException
	{
		HtmlFetcher fetcher = new HtmlFetcher(newsEntity.getUrl());
		fetcher.fetch();
		newsEntity.setHtml((String) fetcher.getFeched());
	}
	
	/**
	 * 解析新闻正文
	 */
	private void parseContent()
	{
		ContentParser parser = new ContentParser(newsEntity);
		parser.parse();
	}
	
	/**
	 * 提取新闻附件链接
	 */
	private void extractMedia()
	{
		LinkExtractor linkEx = new LinkExtractor(newsEntity);
		linkEx.extract();
		ImageExtractor imageEx = new ImageExtractor(newsEntity);
		imageEx.extract();
	}
	
	/**
	 * 下载新闻附件
	 * @throws FetcherException 
	 * @throws InterruptedException 
	 */
	private void fetchMedia() throws FetcherException, InterruptedException
	{
		FetcherGroup fetcherGroup = new FetcherGroup();
		Iterator<Media> it = newsEntity.getMediaList().iterator();
		AbstractFetcher fetcher = null;
		while (it.hasNext()) {
			fetcher = new FileFetcher(it.next());
			fetcherGroup.addFetcher(fetcher);
			fetcherList.add(fetcher);
		}
		fetcherGroup.start();
		fetcherGroup.await();
	}
	
	/**
	 * 过滤出成功的新闻附件
	 */
	private void filterSuccess()
	{
		Iterator<AbstractFetcher> it = fetcherList.iterator();
		ArrayList<Media> mediaList   = newsEntity.getMediaList(); 
		AbstractFetcher fetcher      = null;
		Media media                  = null; 
		long minImageSize            = Looker.gloalConfig.getLong("looker.minImageSize");	//小于指定大小的图片不下载
		while(it.hasNext()) {
			fetcher = it.next();
			media   = (Media) fetcher.getFeched();
			if(!fetcher.isSuccess() || media.getTmpFile().length()<minImageSize )
				mediaList.remove((Media) fetcher.getFeched());
		}
	}

	/**
	 * 实现call接口，方便交给线程池执行
	 */
    @Override
    public NewsEntity call() throws Exception
    {
	    this.archive();
	    return this.getArchived();
    }
}
